#include "stdafx.h"
#include "MaskExporter.h"
#include "CXComp.h"
#include "Paint.h"
#include "MaskSaveDlg.h"
#include <mswin/file_dir.h>
#include <imglib/bmp.h>

//MaskExporter

void MaskExporter::Export()
{
	RendererAPtr deleter(this); //deletes itself if something goes wrong

	if (!PrepareData())
		return;

	MaskSaveDlg SaveDlg("bmp", 
		mswin::seq_name_factory::propose_pattern(mswin::basename(m_Comp.GetFootage().filepath())+".bmp").c_str(), 
		"Bitmap files (*.bmp)|*.bmp||",
		CanSaveInTwoBitDepths(), AfxGetMainWnd());
	SaveDlg.m_ofn.lpstrTitle = "Export Masks to"; 
	if (SaveDlg.DoModal() != IDOK) 
		return;
	m_bSaveInGreyscale =
		SaveDlg.m_bSaveInGreyscale;
	m_SeqNameFactory.init(String(SaveDlg.GetPathName()));

	m_Progress.Create(AfxGetMainWnd());
	m_Progress.Reset(m_Data.size());
	m_Progress.SetWindowText("Exporting masks...");

	mswin::thread::create(true);
	SetThreadPriority(handle(), THREAD_PRIORITY_BELOW_NORMAL);
	deleter.release(); //the object will be deleted in run
}

void MaskExporter::run()
{
	mswin::thread::set_debug_name("MaskExporter");
	AsyncDeleteRenderer deleter(this); //deletes itself on finish

	while (m_Progress.Current() < m_Data.size()) {
		WriteMask(m_Progress.Current(), m_SeqNameFactory.get_next());
		if (!m_Progress.Increment()) {
			AfxMessageBox("Exporting interrupted by user.", MB_ICONEXCLAMATION);
			break;
		}
	}
}

bool MaskExporter::PrepareData()
{
	Span w = m_Comp.GetWorkArea();
	m_Data.resize(w.Size());

	bool SmoothMask = ExportSmoothMasks();
	bool VoidFrames = false;
	for (int n = w.first; n < w.last; ++n) {
		MasksCollection & col = m_Data[n - w.first];
		m_Comp.GetSegments().ListMasksWithCombMode(n, SmoothMask, col);
		if (col.empty())
			VoidFrames = true;
	}
	if (VoidFrames)
		return AfxMessageBox(
			"Some frames in the work area do not contain computed masks.\n"
			"Therefore these frames will be skipped during output. Proceed?",
			MB_ICONEXCLAMATION|MB_OKCANCEL, 0) == IDOK;
	return true;
}

//CrispMaskExporter

void CrispMaskExporter::WriteMask(Size frame, String const & path)
{
	MasksCollection const & col = m_Data[frame];
	if (!col.empty()) {
		BitMask bm;
		MergeMasks(bm, col);
		if (m_bSaveInGreyscale) {
			GreyMask bb =
				img::dichromatic_raster<unsigned char>(bm, 0, 255);
			img::bmp::write8bit(path.c_str(), bb);
		}
		else
			img::bmp::write1bit(path.c_str(), bm);
	}
}

//SmoothMaskExporter

void SmoothMaskExporter::WriteMask(Size frame, String const & path)
{
	MasksCollection const & col = m_Data[frame];
	if (!col.empty()) {
		GreyMask gm;
		MergeMasks(gm, col);
		img::bmp::write8bit(path.c_str(), gm);
	}
}
